from __future__ import annotations

from datetime import datetime
from secrets import token_urlsafe

from sqlalchemy import DateTime, Enum, ForeignKey, String, UniqueConstraint
from sqlalchemy.orm import Mapped, mapped_column, relationship

from app.db.base_class import BaseEntity


class Relationship(BaseEntity):
  __tablename__ = "relationships"
  __table_args__ = (UniqueConstraint("invite_code", name="uq_relationship_invite_code"),)

  initiator_id: Mapped[int] = mapped_column(ForeignKey("users.id"), index=True)
  partner_id: Mapped[int | None] = mapped_column(ForeignKey("users.id"), nullable=True, index=True)
  status: Mapped[str] = mapped_column(
    Enum("pending", "active", "revoked", name="relationship_status"), default="pending"
  )
  invite_code: Mapped[str] = mapped_column(String(32), unique=True, default=lambda: token_urlsafe(8))
  confirmed_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))

  initiator: Mapped["User"] = relationship(
    foreign_keys=[initiator_id], back_populates="initiated_relationships", lazy="joined"
  )
  partner: Mapped["User"] = relationship(
    foreign_keys=[partner_id], back_populates="accepted_relationships", lazy="joined"
  )
